package com.sh.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sh.bean.Resuser;
import com.sh.dao.ResuserMapper;
import com.sh.service.ResuserBiz;
import com.sh.web.model.ResuserVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * Resuser业务实现类，实现了ResuserBiz接口和UserDetailsService接口。
 */
@Service
@Transactional(readOnly = true)
@Slf4j
@RequiredArgsConstructor
public class ResuserBizImpl implements ResuserBiz, UserDetailsService {

    // 使用构造函数注入ResuserMapper，避免循环依赖问题
    private  ResuserMapper resuserMapper;

    // 使用构造函数注入PasswordEncoder，避免循环依赖问题
    private  PasswordEncoder bcryptPasswordEncoder;

    // 以下是被注释掉的通过setter方法注入依赖的方式，不建议使用，容易产生循环依赖问题
     @Autowired
     public void setBcryptPasswordEncoder(PasswordEncoder bcryptPasswordEncoder) {
         this.bcryptPasswordEncoder = bcryptPasswordEncoder;
     }
     @Autowired
     public void setResuserMapper(ResuserMapper resuserMapper) {
         this.resuserMapper = resuserMapper;
     }

    /**
     * 用户注册方法，实现注册新用户的业务逻辑。
     *
     * @param resuserVo 用户注册信息的封装对象
     * @return 注册成功后返回用户ID
     */
    @Transactional
    @Override
    public int regUser(ResuserVo resuserVo) {
        // 创建查询包装器，用于根据用户名进行查询
        QueryWrapper<Resuser> queryWrapper = new QueryWrapper();
        queryWrapper.eq("username", resuserVo.getUsername());
        // 执行查询，获取已存在的用户列表
        List<Resuser> list = resuserMapper.selectList(queryWrapper);
        if (list!= null && list.size() > 0) {
            // 如果用户已存在，抛出运行时异常
            throw new RuntimeException("用户名已存在");
        }
        // 创建新的Resuser对象，用于存储注册用户的信息
        Resuser resuser = new Resuser();
        resuser.setUsername(resuserVo.getUsername());
        // 设置用户密码，这里原本应该使用密码编码器进行加密，但目前直接设置了原始密码
         resuser.setPassword(bcryptPasswordEncoder.encode(resuserVo.getPassword()));
//        resuser.setPassword(resuserVo.getPassword());
        resuser.setEmail(resuserVo.getEmail());
        // 将新用户插入数据库
        resuserMapper.insert(resuser);
        // 返回新用户的ID
        return resuser.getUserid();
    }

    /**
     * 根据用户名加载用户详细信息的方法，实现UserDetailsService接口的方法。
     *
     * @param username 用户名
     * @return 用户详细信息，如果用户不存在则返回null
     * @throws UsernameNotFoundException 如果用户名不存在，抛出该异常
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 创建Lambda查询包装器，用于根据用户名进行查询
        LambdaQueryWrapper<Resuser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Resuser::getUsername, username);
        try {
            // 执行查询，获取用户信息
            Resuser user = resuserMapper.selectOne(wrapper);
            return user;
        } catch (Exception e) {
            // 如果查询过程中出现异常，记录错误日志并返回null
            log.error("用户名不存在");
            return null;
        }
    }
}